package mbp.recorder;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import mbp.core.Intention;
import mbp.core.Resource;
import mbp.core.ResourceUtility;
import mbp.core.ResourceValidation;
import mbp.core.Service;
import mbp.gui.frames.MbpManagerGui;
import mbp.message.ObjectBuilder;
import mbp.message.TagBuilder;

public class ObjectSaver 
{
	private MbpManagerGui mbpManagerGui;
	private TagBuilder tagBuilder;
	private ObjectBuilder objectBuilder;
	
	Logger logger = Logger.getLogger(this.getClass());
	
	public ObjectSaver(MbpManagerGui mbpManagerGui)
	{
		this.mbpManagerGui = mbpManagerGui;
		tagBuilder = new TagBuilder();
		objectBuilder = new ObjectBuilder();
	}
	
	public void saveMbpObjects(String fileName)
	{
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db;
		try {
			db = dbf.newDocumentBuilder();
			Document doc = db.newDocument();
			
			//Stworzenie root
			Element rootElement = doc.createElement("manager");
			doc.appendChild(rootElement);
			
			Element resourcesElement = doc.createElement("resources");
			Element validationsElement = doc.createElement("validations");
			Element utilitiesElement = doc.createElement("utilities");
			Element servicesElement = doc.createElement("services");
			Element intentionsElement = doc.createElement("intentions");
			
			rootElement.appendChild(resourcesElement);
			rootElement.appendChild(validationsElement);
			rootElement.appendChild(utilitiesElement);
			rootElement.appendChild(servicesElement);
			rootElement.appendChild(intentionsElement);
			
			ArrayList<Resource> resourcesList = mbpManagerGui.resourceBuilderGui.getResourcesList();
			ArrayList<ResourceValidation> validationsList = mbpManagerGui.resourceValidateGui.getValidationsList();
			ArrayList<ResourceUtility> utilitiesList = mbpManagerGui.resourceUtilityGui.getUtilitiesList();
			ArrayList<Service> servicesList = mbpManagerGui.serviceBuilderGui.getServicesList();
			ArrayList<Intention> intentionsList = mbpManagerGui.serviceServerGui.getIntentoinsList();
			
			for(int i = 0; i<resourcesList.size(); i++)
			{
				Element resourceElement =  tagBuilder.getResourceTag(doc, 
						objectBuilder.getResourceInfo(resourcesList.get(i)), 
						"resource");
				resourcesElement.appendChild(resourceElement);
			}
			
			for(int i = 0; i<validationsList.size(); i++)
			{
				Element validationElement = tagBuilder.getResourceValidationTag(doc, 
						objectBuilder.getValidationInfo(validationsList.get(i)), 
						"validation");
				validationsElement.appendChild(validationElement);
			}
			
			for(int i = 0; i<utilitiesList.size(); i++)
			{
				Element utilityElement = tagBuilder.getResourceUtilityTag(doc, 
						objectBuilder.getUtilityInfo(utilitiesList.get(i)), 
						"utility");
				utilitiesElement.appendChild(utilityElement);
			}
			
			for(int i = 0; i<servicesList.size(); i++)
			{
				Element serviceElement = tagBuilder.getServiceTag(doc, 
						objectBuilder.getServiceInfo(servicesList.get(i)), 
						"service");
				servicesElement.appendChild(serviceElement);
			}
			
			for(int i = 0; i<intentionsList.size(); i++)
			{
				Element intentionElement = tagBuilder.getIntentionTag(doc, 
						objectBuilder.getIntentionInfo(intentionsList.get(i)), 
						"intention");
				intentionsElement.appendChild(intentionElement);
			}
			
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(fileName));
	 
			transformer.transform(source, result);
			logger.info("File saved!");
			
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void loadMbpObjects(String fileName)
	{
		File fileObjects = new File(fileName);
		DocumentBuilder db;
		Document docObjects;
		try {
			db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			docObjects = db.parse(fileObjects);
			
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			logger.error("ParserConfigurationException", e);
			return;
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			logger.error("SAXException", e);
			return;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.error("IOException", e);
			return;
		}
		
		NodeList resources = docObjects.getElementsByTagName("resources");
		NodeList validations = docObjects.getElementsByTagName("validations");
		NodeList utilities = docObjects.getElementsByTagName("utilities");
		NodeList services = docObjects.getElementsByTagName("services");
		NodeList intentions = docObjects.getElementsByTagName("intentions");
		
		Element resourcesElement = (Element)resources.item(0);
		NodeList resourceItems = resourcesElement.getElementsByTagName("resource");
		for(int i=0; i<resourceItems.getLength(); i++)
		{
			Resource rc = objectBuilder.getResource(tagBuilder.getResourceInfo((Element) resourceItems.item(i)));
			logger.info("Created new Resource: " + rc.getType().getResourceTypeName());
			mbpManagerGui.resourceBuilderGui.AddResource(rc);
		}
		
		Element validationsElement = (Element) validations.item(0);
		NodeList validationItems = validationsElement.getElementsByTagName("validation");
		for(int i=0; i<validationItems.getLength(); i++)
		{
			ResourceValidation rv = objectBuilder.getResourceValidation(tagBuilder.getValidationInfo((Element) validationItems.item(i)));
			logger.info("Created new ResourceValidation: " + rv.getType().getResourceTypeName());
			mbpManagerGui.resourceValidateGui.AddValuesRangeFunction(rv);
		}
		
		Element utilitiesElement = (Element) utilities.item(0);
		NodeList utilityItems = utilitiesElement.getElementsByTagName("utility");
		for(int i=0; i<utilityItems.getLength(); i++)
		{
			ResourceUtility ru = objectBuilder.getResourceUtility(tagBuilder.getUtilityInfo((Element) utilityItems.item(i)));
			logger.info("Created new ResourceUtility: " + ru.getType().getResourceTypeName());
			mbpManagerGui.resourceUtilityGui.AddUtilityFunction(ru);
		}
		
		Element servicesElement = (Element) services.item(0);
		NodeList serviceItems = servicesElement.getElementsByTagName("service");
		for(int i=0; i<serviceItems.getLength(); i++)
		{
			Service srv = objectBuilder.getService(tagBuilder.getServiceInfo((Element) serviceItems.item(i)));
			logger.info("Created new Service: " + srv.getType().getServiceTypeName());
			mbpManagerGui.serviceBuilderGui.addService(srv);
		}
		
		Element intentionsElement = (Element) intentions.item(0);
		NodeList intentionItems = intentionsElement.getElementsByTagName("intention");
		for(int i=0; i<intentionItems.getLength(); i++)
		{
			Intention intention = objectBuilder.getIntention(tagBuilder.getIntentionInfo((Element) intentionItems.item(i)));
			logger.info("Created new Intention: " + intention.getServiceType().getServiceTypeName());
			mbpManagerGui.serviceServerGui.addIntention(intention);
		}
	}

}
